package com.ac.scum.log.task.face.log.counsumer.stages;

import com.ac.common.core.id.SnowflakeIdGenerator;
import com.ac.scum.log.bean.Player;
import com.ac.scum.log.bean.ServerFTPLogChat;
import com.ac.scum.log.task.face.log.counsumer.LogConsumer;
import com.ac.scum.log.task.mapper.log.ServerFTPLogChatMapper;
import com.ac.scum.log.task.utils.queue.FTPQueueItem;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@AllArgsConstructor
public class ChatLogConsumer implements LogConsumer {
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final ServerFTPLogChatMapper serverFTPLogChatMapper;

    @Override
    public void consumerLog(FTPQueueItem ftpQueueItem) {
        try {
            List<Long> robotSteamIds = getRobotSteamIds(ftpQueueItem);
            String chatRegex = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): '(\\d+):(.*?)\\((\\d+)\\)' '(\\w+): (.*)'";
            String commandRegex = "(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): '(\\d+):(.*?)\\((\\d+)\\)'(?: Command: '(.*?)')?";
            writeAllPlayerInfoInCache(ftpQueueItem);

            Pattern chatPattern = Pattern.compile(chatRegex);
            Pattern commandPattern = Pattern.compile(commandRegex);

            List<ServerFTPLogChat> logChatList = Lists.newArrayList();
            for (GameLogLine line : splitLine(ftpQueueItem)) {
                if (!robotSteamIds.isEmpty() && robotSteamIds.stream().anyMatch(steamId -> line.getLineContext().contains(steamId.toString()))) {
                    continue;
                }
                String lineContext = line.getLineContext();
                Matcher matcher = chatPattern.matcher(lineContext);
                ServerFTPLogChat logChat = new ServerFTPLogChat();
                logChat.setId(snowflakeIdGenerator.nextId());
                logChat.setServerId(ftpQueueItem.getServer().getId());
                logChat.setFileId(ftpQueueItem.getFileId());
                logChat.setLineStart(line.getStartByte());
                logChat.setLineEnd(line.getEndByte());
                logChat.setCreateTime(LocalDateTime.now());
                if (matcher.matches()) {
                    logChat.setServerTime(parseTimestamp(matcher.group(1), ftpQueueItem));
                    logChat.setType(getChatType(matcher.group(5)));
                    logChat.setPlayerSteamId(Long.parseLong(matcher.group(2)));
                    Player player = getOrInsertPlayerServer(logChat.getPlayerSteamId(), logChat.getServerId(), matcher.group(3));
                    logChat.setPlayerId(player.getId());
                    logChat.setContent(matcher.group(6));
                } else if (lineContext.contains("Command:")) {
                    matcher = commandPattern.matcher(lineContext);
                    if (matcher.matches()) {
                        logChat.setServerTime(parseTimestamp(matcher.group(1), ftpQueueItem));
                        logChat.setType(4);
                        logChat.setPlayerSteamId(Long.parseLong(matcher.group(2)));
                        Player player = getOrInsertPlayerServer(logChat.getPlayerSteamId(), logChat.getServerId(), matcher.group(3));
                        logChat.setPlayerId(player.getId());
                        logChat.setContent(matcher.group(5));
                    } else {
                        commitDiscardLog(ftpQueueItem, line, "chat for one else");
                    }
                } else {
                    commitDiscardLog(ftpQueueItem, line, "chat for two else");
                }
                if (logChat.getContent().length() > 2000) {
                    logChat.setContent(logChat.getContent().substring(0, 2000));
                }
                logChatList.add(logChat);
            }
            logChatList.forEach(serverFTPLogChatMapper::insert);
        } catch (Exception e) {
            log.error("聊天日志任务异常", e);
        }
    }

    private Integer getChatType(String type) {
        //类型(1公共 2小队 3附近 4管理员)
        return switch (type) {
            case "Global" -> 1;
            case "Squad" -> 2;
            case "Local" -> 3;
            case "Admin" -> 4;
            default -> 9;
        };
    }
}
